package com.rizzo.analytics.services.web.controller.v1;

import com.rizzo.analytics.domain.account.Account;
import com.rizzo.analytics.domain.trend.Trend;
import com.rizzo.analytics.domain.trend.TrendType;
import com.rizzo.infrastructure.dark.DarkLaunch;
import com.rizzo.infrastructure.performance.Monitor;
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
import com.wordnik.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

@Controller("trendController")
@RequestMapping(value = "/trend", produces = "application/json")
@Api(value = "/trend", description = "Operations about Trending")
public class TrendController extends RizzoController {

	private static final Logger LOGGER = LoggerFactory.getLogger(TrendController.class);

	@Monitor(userBound = true)
	@PreAuthorize("hasRole('" + Account.ROLE_USER + "')")
	@DarkLaunch(name = "get-trend")
	@RequestMapping(value = "/{application}", method = RequestMethod.GET, produces = "application/json")
	@ApiOperation(value = "Trending data",
			notes = "This endpoint provides trending data about an application. " +
					"This endpoint can only be called when logged in and will only return the " + PAGE_SIZE + " first entries!",
			responseClass = "com.rizzo.analytics.domain.trend.Trend")
	public Trend getTrend(
			@PathVariable(value = "application")
			@ApiParam(name = "application", required = true,
					value = "The full name of the application (see output of '/application' for possible values)") String application) {
		final String user = getUsernameFromContext();
		LOGGER.debug("Called trend of [application : '{}'] and [user : '{}']", application, user);
		return analyticsDelegator.getTrend(user, application, WILDCARD, WILDCARD, WILDCARD, Integer.parseInt(PAGE_SIZE), 0, TrendType.ALL);
	}

	@Monitor(userBound = true)
	@PreAuthorize("hasRole('" + Account.ROLE_USER + "')")
	@DarkLaunch(name = "get-trend-with-criteria")
	@RequestMapping(value = "/{application}/{category}", method = RequestMethod.GET, produces = "application/json")
	@ApiOperation(value = "Paged trending data",
			notes = "This endpoint provides trending data about an application. " +
					"Results from this endpoint are pageable and filterable by category, instanceName, instanceIndex. " +
					"This endpoint can only be called when logged in!",
			responseClass = "com.rizzo.analytics.domain.trend.Trend")
	public Trend getTrendWithCriteria(
			@PathVariable(value = "application")
			@ApiParam(name = "application", required = true,
					value = "The full name of the application (see output of '/application' for possible values)") String application,
			@PathVariable("category")
			@ApiParam(name = "category", required = true,
					value = "The category or method of the trended service (wildcards '*' are allowed but case-sensitive)") String category,
			@RequestParam(value = "instanceName", defaultValue = WILDCARD, required = false)
			@ApiParam(name = "instanceName", defaultValue = WILDCARD, required = false,
					value = "The instanceName from which the trending data originated (wildcards '*' are allowed)") String instanceName,
			@RequestParam(value = "instanceIndex", defaultValue = WILDCARD, required = false)
			@ApiParam(name = "instanceIndex", defaultValue = WILDCARD, required = false,
					value = "The instanceIndex from which the trending data originated (wildcards '*' are allowed)") String instanceIndex,
			@RequestParam(value = "limit", defaultValue = PAGE_SIZE, required = false)
			@ApiParam(name = "limit", defaultValue = PAGE_SIZE, required = false, allowableValues = TREND_PAGE_LIMIT_RANGE,
					value = "The page-size/limit of the results") long limit,
			@RequestParam(value = "offset", defaultValue = "0", required = false)
			@ApiParam(name = "offset", defaultValue = "0", required = false,
					value = "The page-offset of the results") long offset,
			@RequestParam(value = "trendType", defaultValue = "ALL", required = false)
			@ApiParam(name = "trendType", defaultValue = "ALL", required = false, allowableValues = TrendType.allowableValues,
					value = "The type of trending data to return") TrendType trendType) {
		final String user = getUsernameFromContext();
		LOGGER.debug("Called trend of [application : '{}'] and [user : '{}'] for [category : '{}']", application, user, category);
		return analyticsDelegator.getTrend(user, application, instanceName, instanceIndex, category, limit, offset, trendType);
	}

}
